/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.icee.myth.server.gm;

import com.icee.myth.server.actor.Human;
import com.icee.myth.protobuf.InternalCommonProtocol.M2SGmProto;
import com.icee.myth.server.GameServer;
import com.icee.myth.log.GameLogger;
import com.icee.myth.log.message.FileDebugGameLogMessage;
import com.icee.myth.log.message.builder.GameLogMessageBuilder;
import com.icee.myth.server.base.occupy.OccupyInfos;
import com.icee.myth.server.levelup.HumanLevelsConfig;
import com.icee.myth.server.levelup.HumanRanksConfig;
import com.icee.myth.utils.Consts;
import java.util.List;

/**
 * 处理来自Console的命令
 * @author liuxianke
 */
public class GMOper {

    public static final int MAXCOOLDOWNNUM = 200;

    public static void handle(M2SGmProto gmProto) {
        try {
            int playerId = gmProto.getPlayerId();
            String cmd = gmProto.getGmCmd();
            List<String> args = gmProto.getArgsList();
            if (cmd.equalsIgnoreCase("stat")) {
                stat();
            } else if (cmd.equalsIgnoreCase("calculateCardDrawRate")) {
                if (args.size() >= 2) {
                    calculateCardDrawRate(Integer.parseInt(args.get(0)), Integer.parseInt(args.get(1)));
                }
            } else if (cmd.equalsIgnoreCase("printUninitOccupyInfo")) { // 用于调试据点功能
                if (args.size() >= 0) {
                    printUninitOccupyInfo();
                }
            } else if (cmd.equalsIgnoreCase("printFightingOccupyInfo")) { // 用于调试据点功能
                if (args.size() >= 0) {
                    printFightingOccupyInfo();
                }
            } else {
                Human human = GameServer.INSTANCE.getHuman(playerId);
                if (human != null && human.inGame) {
                    if (cmd.equalsIgnoreCase("increaseSilver")) {
                        if (args.size() >= 1) {
                            increaseSilver(human, Integer.parseInt(args.get(0)));
                        }
                    } else if (cmd.equalsIgnoreCase("decreaseSilver")) {
                        if (args.size() >= 1) {
                            decreaseSilver(human, Integer.parseInt(args.get(0)));
                        }
                    } else if (cmd.equalsIgnoreCase("increaseGold")) {
                        if (args.size() >= 1) {
                            increaseGold(human, Integer.parseInt(args.get(0)));
                        }
                    } else if (cmd.equalsIgnoreCase("decreaseGold")) {
                        if (args.size() >= 1) {
                            decreaseGold(human, Integer.parseInt(args.get(0)));
                        }
                    } else if (cmd.equalsIgnoreCase("increaseGold1")) {
                        if (args.size() >= 1) {
                            increaseGold1(human, Integer.parseInt(args.get(0)));
                        }
                    } else if (cmd.equalsIgnoreCase("setlv")) {
                        if (args.size() >= 1) {
                            setLevel(human, Integer.parseInt(args.get(0)));
                        }
                    } else if (cmd.equalsIgnoreCase("setRank")) {
                        if (args.size() >= 1) {
                            setRank(human, Integer.parseInt(args.get(0)));
                        }
                    } else if (cmd.equalsIgnoreCase("addItem")) {
                        if (args.size() >= 2) {
                            addItem(human, Integer.parseInt(args.get(0)), Integer.parseInt(args.get(1)));
                        }
                    } else if (cmd.equalsIgnoreCase("unlockStage")) {
                        if (args.size() >= 1) {
                            unlockStage(human, Integer.parseInt(args.get(0)));
                        }
                    } else if (cmd.equalsIgnoreCase("increaseExp")) {
                        if (args.size() >= 1) {
                            increaseExp(human, Integer.parseInt(args.get(0)));
                        }
                    } else if (cmd.equalsIgnoreCase("increaseEnergy")) {
                        if (args.size() >= 1) {
                            increaseEnergy(human, Integer.parseInt(args.get(0)));
                        }
                    } else if (cmd.equalsIgnoreCase("decreaseEnergy")) {
                        if (args.size() >= 1) {
                            decreaseEnergy(human, Integer.parseInt(args.get(0)));
                        }
                    } else if (cmd.equalsIgnoreCase("increaseToken")) {
                        if (args.size() >= 1) {
                            increaseToken(human, Integer.parseInt(args.get(0)));
                        }
                    } else if (cmd.equalsIgnoreCase("clearviplevel")) {
                        clearVipLevel(human);
                    } else if (cmd.equalsIgnoreCase("addCard")) {
                        if (args.size() >= 2) {
                            addCard(human, Integer.parseInt(args.get(0)), Integer.parseInt(args.get(1)));
                        }
                    } else if (cmd.equalsIgnoreCase("calculateWinRate")) {
                        if (args.size() >= 3) {
                            calculateWinRate(human, Integer.parseInt(args.get(0)), Integer.parseInt(args.get(1)), Integer.parseInt(args.get(2)));
                        }
                    } else if (cmd.equalsIgnoreCase("generateBattleResult")) {
                        if (args.size() >= 4) {
                            generateBattleResult(human, Integer.parseInt(args.get(0)), Integer.parseInt(args.get(1)), Integer.parseInt(args.get(2)), args.get(3));
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private static void increaseSilver(Human human, int nInc) {
        human.increaseSilver(nInc, Consts.SOUL_CHANGE_LOG_TYPE_GM_INCREASE, Consts.SOUL_CHANGE_LOG_SUBTYPE_NONE, true);
        GameLogger.getlogger().log(GameLogMessageBuilder.buildFileDebugGameLogMessage(
                FileDebugGameLogMessage.DebugLogType.DEBUGLOGTYPE_DEBUG,
                "GM--- playerId: " + human.id + " increase silver: " + nInc));
    }

    private static void decreaseSilver(Human human, int nDec) {
        human.decreaseSilver(nDec, Consts.SOUL_CHANGE_LOG_TYPE_GM_DECREASE, Consts.SOUL_CHANGE_LOG_SUBTYPE_NONE, true);
        GameLogger.getlogger().log(GameLogMessageBuilder.buildFileDebugGameLogMessage(
                FileDebugGameLogMessage.DebugLogType.DEBUGLOGTYPE_DEBUG,
                "GM--- playerId: " + human.id + " decrease silver: " + nDec));
    }

    private static void increaseGold(Human human, int nInc) {
        human.increaseGold(0, nInc, Consts.SOUL_CHANGE_LOG_TYPE_GM_INCREASE, Consts.SOUL_CHANGE_LOG_SUBTYPE_NONE, true);
        GameLogger.getlogger().log(GameLogMessageBuilder.buildFileDebugGameLogMessage(
                FileDebugGameLogMessage.DebugLogType.DEBUGLOGTYPE_DEBUG,
                "GM--- playerId: " + human.id + " increase gold: " + nInc));
    }

    private static void decreaseGold(Human human, int nDec) {
        human.decreaseGold(nDec, Consts.SOUL_CHANGE_LOG_TYPE_GM_DECREASE, Consts.SOUL_CHANGE_LOG_SUBTYPE_NONE, true, false);
        GameLogger.getlogger().log(GameLogMessageBuilder.buildFileDebugGameLogMessage(
                FileDebugGameLogMessage.DebugLogType.DEBUGLOGTYPE_DEBUG,
                "GM--- playerId: " + human.id + " decrease gold: " + nDec));
    }

    private static void increaseGold1(Human human, int nInc) {
        human.increaseGold(nInc, 0, Consts.SOUL_CHANGE_LOG_TYPE_GM_INCREASE_YELLOWSOUL1, Consts.SOUL_CHANGE_LOG_SUBTYPE_NONE, true);
        GameLogger.getlogger().log(GameLogMessageBuilder.buildFileDebugGameLogMessage(
                FileDebugGameLogMessage.DebugLogType.DEBUGLOGTYPE_DEBUG,
                "GM--- playerId: " + human.id + " increase gold1: " + nInc));
    }

    private static void setLevel(Human human, int level) {
        int maxLevel = HumanLevelsConfig.INSTANCE.maxLevel;
        if (level <= maxLevel) {
            if (level > human.lv) {
                human.levelup(level - human.lv, true);
            }
            GameLogger.getlogger().log(GameLogMessageBuilder.buildFileDebugGameLogMessage(
                    FileDebugGameLogMessage.DebugLogType.DEBUGLOGTYPE_DEBUG,
                    "GM--- playerId: " + human.id + " set level " + level));
        } else {
            GameLogger.getlogger().log(GameLogMessageBuilder.buildFileDebugGameLogMessage(
                    FileDebugGameLogMessage.DebugLogType.DEBUGLOGTYPE_ERROR,
                    "GM--- playerId: " + human.id + " can't set level " + level + " bigger than " + maxLevel));
        }
    }

    private static void setRank(Human human, int rank) {
        int maxLevel = HumanRanksConfig.INSTANCE.maxRank;
        if (rank <= maxLevel) {
            if (rank > human.rankLv) {
                human.rankLevelup(rank - human.rankLv, true);
            }
            GameLogger.getlogger().log(GameLogMessageBuilder.buildFileDebugGameLogMessage(
                    FileDebugGameLogMessage.DebugLogType.DEBUGLOGTYPE_DEBUG,
                    "GM--- playerId: " + human.id + " set rank " + rank));
        } else {
            GameLogger.getlogger().log(GameLogMessageBuilder.buildFileDebugGameLogMessage(
                    FileDebugGameLogMessage.DebugLogType.DEBUGLOGTYPE_ERROR,
                    "GM--- playerId: " + human.id + " can't set rank " + rank + " bigger than " + maxLevel));
        }
    }

    private static void addItem(Human human, int itemId, int itemNum) {
        human.items.addItem(itemId, itemNum, true);
        GameLogger.getlogger().log(GameLogMessageBuilder.buildFileDebugGameLogMessage(
                FileDebugGameLogMessage.DebugLogType.DEBUGLOGTYPE_DEBUG,
                "GM--- playerId: " + human.id + " add item, itemId" + itemId + " itemNum: " + itemNum));
    }

    private static void unlockStage(Human human, int stageId) {
        human.stages.finishState(stageId-1, false, true);
        GameLogger.getlogger().log(GameLogMessageBuilder.buildFileDebugGameLogMessage(
                FileDebugGameLogMessage.DebugLogType.DEBUGLOGTYPE_DEBUG,
                "GM--- playerId: " + human.id + " unlock stage" + stageId));
    }

    private static void stat() {
        GameLogger.getlogger().log(GameLogMessageBuilder.buildFileDebugGameLogMessage(
                FileDebugGameLogMessage.DebugLogType.DEBUGLOGTYPE_DEBUG,
                "GM--- stat \n player count: " + GameServer.INSTANCE.players.size()));
    }

    private static void increaseExp(Human human, int exp) {
        human.increaseExperience(exp, Consts.SOUL_CHANGE_LOG_TYPE_GM_INCREASE, Consts.SOUL_CHANGE_LOG_SUBTYPE_NONE, true);
        GameLogger.getlogger().log(GameLogMessageBuilder.buildFileDebugGameLogMessage(
                FileDebugGameLogMessage.DebugLogType.DEBUGLOGTYPE_DEBUG,
                "GM--- playerId: " + human.id + " increaseExp " + exp));
    }

    private static void increaseEnergy(Human human, int num) {
        human.increaseEnergy(num, true);
        GameLogger.getlogger().log(GameLogMessageBuilder.buildFileDebugGameLogMessage(
                FileDebugGameLogMessage.DebugLogType.DEBUGLOGTYPE_DEBUG,
                "GM--- playerId: " + human.id + " increaseEnergy " + num));
    }

    private static void decreaseEnergy(Human human, int num) {
        human.decreaseEnergy(num, true);
        GameLogger.getlogger().log(GameLogMessageBuilder.buildFileDebugGameLogMessage(
                FileDebugGameLogMessage.DebugLogType.DEBUGLOGTYPE_DEBUG,
                "GM--- playerId: " + human.id + " decreaseEnergy " + num));
    }

    private static void increaseToken(Human human, int num) {
        human.increaseToken(num, true);
        GameLogger.getlogger().log(GameLogMessageBuilder.buildFileDebugGameLogMessage(
                FileDebugGameLogMessage.DebugLogType.DEBUGLOGTYPE_DEBUG,
                "GM--- playerId: " + human.id + " increaseToken " + num));
    }

    private static void clearVipLevel(Human human) {
        human.vip.clearVipLevel(true);
        GameLogger.getlogger().log(GameLogMessageBuilder.buildFileDebugGameLogMessage(
                FileDebugGameLogMessage.DebugLogType.DEBUGLOGTYPE_DEBUG,
                "GM--- clearVipLevel"));
    }

    private static void addCard(Human human, int cardId, int level) {
        human.cards.addCard(cardId, level, 0, true);
        GameLogger.getlogger().log(GameLogMessageBuilder.buildFileDebugGameLogMessage(
                FileDebugGameLogMessage.DebugLogType.DEBUGLOGTYPE_DEBUG,
                "GM--- playerId: " + human.id + " add card, cardId " + cardId + " level " + level));
    }

    public static void calculateWinRate(Human human, int battleId, int helperCardId, int helperCardLevel) {
        human.calculateWinRate(battleId, helperCardId, helperCardLevel);
        GameLogger.getlogger().log(GameLogMessageBuilder.buildFileDebugGameLogMessage(
                FileDebugGameLogMessage.DebugLogType.DEBUGLOGTYPE_DEBUG,
                "GM--- playerId: " + human.id + " calculate battle[" + battleId + "] win rate"));
    }

    public static void generateBattleResult(Human human, int battleId, int helperCardId, int helperCardLevel, String outputFileName) {
        human.generateBattleResult(battleId, helperCardId, helperCardLevel, outputFileName);
        GameLogger.getlogger().log(GameLogMessageBuilder.buildFileDebugGameLogMessage(
                FileDebugGameLogMessage.DebugLogType.DEBUGLOGTYPE_DEBUG,
                "GM--- playerId: " + human.id + " generate battle[" + battleId + "] result"));
    }

    public static void calculateCardDrawRate(int cardDrawId, int drawTimes) {
        // TODO:
        GMCalculateCardDrawRate gmCalculateCardDrawRate = new GMCalculateCardDrawRate(cardDrawId, drawTimes);
        GameServer.INSTANCE.executeGMCalculateCardDrawRate(gmCalculateCardDrawRate);
        GameLogger.getlogger().log(GameLogMessageBuilder.buildFileDebugGameLogMessage(
                FileDebugGameLogMessage.DebugLogType.DEBUGLOGTYPE_DEBUG,
                "GM--- calculate card draw[" + cardDrawId + "] rate"));
    }

    public static void printUninitOccupyInfo() {
        // 打印出未初始化的臣属信息
        OccupyInfos.INSTANCE.printUninitOccupyInfo();
    }

    public static void printFightingOccupyInfo() {
        // 打印出战斗中的臣属信息
        OccupyInfos.INSTANCE.printFightingOccupyInfo();
    }
}
